#include "parse.h"

void init_parser( ) {
	init_log( );
	path = malloc( ( 18 + strlen( PREFIX ) ) * sizeof( char ) );
	path = strcpy( path, PREFIX ) ;
	path = strcat( path, "etc/urlstorage.xml" );
	
	uris[ 0] = "http://";
	uris[ 1] = "https://";
	uris[ 2] = "mailto:";
	uris[ 3] = "feed://";
	uris[ 4] = "rss://";
	uris[ 5] = "ftp://";
	uris[ 6] = "sftp://";
	uris[ 7] = "see://";
	uris[ 8] = "afp://";
	uris[ 9] = "smb://";
	uris[10] = "spotify://";
	uris[11] = "irc://";
	uris[12] = "ssh://";
	uris[13] = "jabber://";
	uris[14] = "xmpp://";
	uris[15] = "vnc://";
	uris[16] = "itms://";
}

void parse( char *in, char *out ) {
	if( str_has_prefx( in, "GET /compress?q=" ) )
		send_compress( in, out );
	else if( str_has_prefx( in, "GET / " ) )
		send_main_page( out );
	else if( str_has_prefx( in, "GET /" ) )
		send_expand( in, out );
	else
		send_error( in, out );
}

void get_addr( char *request, char *addr, int n ) {
	int i;
	int max;
	if( n == 16 )
		max= 2048;
	else if( n == 5 )
		max= 32;
	for( i =n; request[ i ] != ' ' ; i++ )
		addr[ i- n] = request[ i ];
	addr[i - n] = '\0';
}

void send_compress( char *in, char * out ) {
	char addr[ 2048 ];
	get_addr( in, addr, COMPRESS_NUM );
	
	FILE *fp;
	if( (fp = fopen( path, "r+" ) ) == NULL )
		perror( "send_compress( ): fopen urlstorage" );
	
	/* get the file size */
	fseek( fp, 0, SEEK_END ); 
	int fsize = ftell( fp );
	fseek( fp, 0, SEEK_SET );
	
	char fcontent[ fsize];
	
	/* put the file content into fcontent */
	int c = getc( fp );
	int i;
	for( i=0; c != EOF; i++ ) {
		fcontent[ i] = c;
		c = getc (fp);
	}

	char id[32];
	memset( id, 0, sizeof( id ) );

	xml_last_id( fcontent, id );
	fseek( fp, -11, SEEK_END );
	
	#pragma mark uri handling
	
	int uri = -1;
	
	for( i=0; i < URI_COUNT; i++ ) {
		if( str_has_prefx( addr, uris[i] ) ) {
			uri = i;
			break;
		}
	}
	
	if( uri == -1 ) {  /* add the prefix 'http://', because there is no known one */
		char sec_addr[ strlen(addr) ];
		strcpy( sec_addr, addr );
		sprintf( addr, "http://%s\0", sec_addr );
	}
	
	if( str_has_prefx( addr, "http://ctu.ath.cx/" ) ) {
		strcpy( out, "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html; charset=UTF-8\r\n\r\nError: You cannot create compressed urls referring to CTU" );
		return;
	}
	
	if( strstr( fcontent, addr ) != NULL ) { /* if the url already exists */
		xml_get_id( fcontent, addr, id );
	}
	else {
		xml_increment_id( id );
		fprintf( fp, "\t<url id=\"%s\">%s</url>\n</database>", id, addr ); // save the new id
	}
	
	#pragma mark prepare output buffer
	
	sprintf( out, "%s%s%s\0", http_head, HOST_ADDR, id );
	
	fclose( fp );
	
	#ifdef WANT_LOG
		char logstr[ strlen( addr ) + strlen( id ) + 21 ];
		sprintf( logstr, "compressed %s to %s", addr, id );
		log( STD, logstr );
	#endif
	
	return;
}

void send_main_page( char *out ) {
	#ifdef WANT_LOG
		log( STD, "user requested main page." );
	#endif
	strcpy( out, "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html; charset=UTF-8\r\n\r\n<head><frameset><frame src=\"http://frocensoftware.bplaced.net/ctu/webinterface/\" width=100% height=100% /></frameset></head>" );
}

void send_expand( char *in, char *out ) {

	char id[ 32];
	get_addr( in, id, EXPAND_NUM );

	FILE *fp;
	if( (fp = fopen( path, "r+" ) ) == NULL )
		perror( "fopen urlstorage" );
	
	fseek( fp, 0, SEEK_END );
	int fsize = ftell( fp );
	fseek( fp, 0, SEEK_SET );
	
	char fcontent[ fsize];
	
	/* put the file content into fcontent */
	{
	int c = getc( fp );
	int i;
	for( i=0; c != EOF; i++ ) {
		fcontent[ i] = c;
		c = getc (fp);
	}
	fcontent[ i]= '\0';
	
	fclose( fp ); 
	}
	/* ---------------------------------- */
	
	char addr[ 2048 ];
	memset( addr, 0, sizeof( addr ) );
	
	xml_get_url( fcontent, id, addr );
		
	if( strlen( addr ) == 0 ) {
		strcpy( out, http_head );
		strcat( out, "<h1>Error:</h1>The id, you requested was not found in our database. Please check your link to the page or try another one." );
		return;
	}
	
	sprintf( out, "%s%s\r\n\r\n\0", redirect_head, addr );
	#ifdef WANT_LOG
		char logstr[ 40 ];
		sprintf( logstr, "expanded %s", id );
		log( STD, logstr );
	#endif
}

void send_error( char *in, char *out ) {
	strcpy( out, "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html; charset=UTF-8\r\n\r\nError, file not found." );
}

